#include "pcap.h"


int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
int res;
char errbuf[PCAP_ERRBUF_SIZE];
struct tm ltime;
char timestr[16];
struct pcap_pkthdr *header;
const u_char *pkt_data;
time_t local_tv_sec;
    
    
    /* Retrieve the device list on the local machine */
    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }
    
    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf_s("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
    
    /* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    /* Open the device */
    if ( (adhandle= pcap_open(d->name,          // name of the device
                              65536,            // portion of the packet to capture. 
                                                // 65536 guarantees that the whole packet will be captured on all the link layers
                              PCAP_OPENFLAG_PROMISCUOUS,    // promiscuous mode
                              1000,             // read timeout
                              NULL,             // authentication on the remote machine
                              errbuf            // error buffer
                              ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
    
    printf("\nlistening on %s...\n", d->description);
    
    /* At this point, we don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);
    
    /* Retrieve the packets */
    while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
        
        if(res == 0)
            /* Timeout elapsed */
            continue;
        
        /* convert the timestamp to readable format */
        local_tv_sec = header->ts.tv_sec;
        localtime_s(&ltime, &local_tv_sec);
        strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);
        
        printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
    }
    
    if(res == -1){
        printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
        return -1;
    }
    
    return 0;
}


//===================================================================================================
//#include "pcap.h"
//
///* prototype of the packet handler */
//void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
//
//int main()
//{
//pcap_if_t *alldevs;
//pcap_if_t *d;
//int inum;
//int i=0;
//pcap_t *adhandle;
//char errbuf[PCAP_ERRBUF_SIZE];
//    
//    /* Retrieve the device list on the local machine */
//    if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
//    {
//        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
//        exit(1);
//    }
//    
//    /* Print the list */
//    for(d=alldevs; d; d=d->next)
//    {
//        printf("%d. %s", ++i, d->name);
//        if (d->description)
//            printf(" (%s)\n", d->description);
//        else
//            printf(" (No description available)\n");
//    }
//    
//    if(i==0)
//    {
//        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
//        return -1;
//    }
//    
//    printf("Enter the interface number (1-%d):",i);
//    scanf_s("%d", &inum);
//    
//    if(inum < 1 || inum > i)
//    {
//        printf("\nInterface number out of range.\n");
//        /* Free the device list */
//        pcap_freealldevs(alldevs);
//        return -1;
//    }
//    
//    /* Jump to the selected adapter */
//    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
//    
//    /* Open the device */
//    if ( (adhandle= pcap_open(d->name,          // name of the device
//                              65536,            // portion of the packet to capture
//                                                // 65536 guarantees that the whole packet will be captured on all the link layers
//                              PCAP_OPENFLAG_PROMISCUOUS,    // promiscuous mode
//                              1000,             // read timeout
//                              NULL,             // authentication on the remote machine
//                              errbuf            // error buffer
//                              ) ) == NULL)
//    {
//        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
//        /* Free the device list */
//        pcap_freealldevs(alldevs);
//        return -1;
//    }
//    
//    printf("\nlistening on %s...\n", d->description);
//    
//    /* At this point, we don't need any more the device list. Free it */
//    pcap_freealldevs(alldevs);
//    
//    /* start the capture */
//    pcap_loop(adhandle, 0, packet_handler, NULL);
//    
//    return 0;
//}
//
//
///* Callback function invoked by libpcap for every incoming packet */
//void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
//{
//    struct tm ltime;
//    char timestr[16];
//    time_t local_tv_sec;
//
//    /*
//     * unused variables
//     */
//    (VOID)(param);
//    (VOID)(pkt_data);
//
//    /* convert the timestamp to readable format */
//    local_tv_sec = header->ts.tv_sec;
//    localtime_s(&ltime, &local_tv_sec);
//    strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);
//    
//    printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
//    
//}

///* =====================================================================================================
// * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
// * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
// * All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions
// * are met:
// *
// * 1. Redistributions of source code must retain the above copyright
// * notice, this list of conditions and the following disclaimer.
// * 2. Redistributions in binary form must reproduce the above copyright
// * notice, this list of conditions and the following disclaimer in the
// * documentation and/or other materials provided with the distribution.
// * 3. Neither the name of the Politecnico di Torino, CACE Technologies 
// * nor the names of its contributors may be used to endorse or promote 
// * products derived from this software without specific prior written 
// * permission.
// *
// * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
// */
//
//#include <stdio.h>
//
//#include "pcap.h"
//
//#ifndef WIN32
//    #include <sys/socket.h>
//    #include <netinet/in.h>
//#else
//    #include <winsock.h>
//#endif
//
//
//// Function prototypes
//void ifprint(pcap_if_t *d);
//char *iptos(u_long in);
//char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen);
//
//
//int main()
//{
//  pcap_if_t *alldevs;
//  pcap_if_t *d;
//  char errbuf[PCAP_ERRBUF_SIZE+1];
//  char source[PCAP_ERRBUF_SIZE+1];
//
//  printf("Enter the device you want to list:\n"
//            "rpcap://              ==> lists interfaces in the local machine\n"
//            "rpcap://hostname:port ==> lists interfaces in a remote machine\n"
//            "                          (rpcapd daemon must be up and running\n"
//            "                           and it must accept 'null' authentication)\n"
//            "file://foldername     ==> lists all pcap files in the give folder\n\n"
//            "Enter your choice: ");
//
//  fgets(source, PCAP_ERRBUF_SIZE, stdin);
//  source[PCAP_ERRBUF_SIZE] = '\0';
//
//  /* Retrieve the interfaces list */
//  if (pcap_findalldevs_ex(source, NULL, &alldevs, errbuf) == -1)
//  {
//    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
//    exit(1);
//  }
//
//  /* Scan the list printing every entry */
//  for(d=alldevs;d;d=d->next)
//  {
//    ifprint(d);
//  }
//
//  pcap_freealldevs(alldevs);
//
//  return 1;
//}
//
//
//
///* Print all the available information on the given interface */
//void ifprint(pcap_if_t *d)
//{
//  pcap_addr_t *a;
//  char ip6str[128];
//
//  /* Name */
//  printf("%s\n",d->name);
//
//  /* Description */
//  if (d->description)
//    printf("\tDescription: %s\n",d->description);
//
//  /* Loopback Address*/
//  printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
//
//  /* IP addresses */
//  for(a=d->addresses;a;a=a->next) {
//    printf("\tAddress Family: #%d\n",a->addr->sa_family);
//  
//    switch(a->addr->sa_family)
//    {
//      case AF_INET:
//        printf("\tAddress Family Name: AF_INET\n");
//        if (a->addr)
//          printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
//        if (a->netmask)
//          printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
//        if (a->broadaddr)
//          printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
//        if (a->dstaddr)
//          printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
//        break;
//
//      case AF_INET6:
//        printf("\tAddress Family Name: AF_INET6\n");
//        if (a->addr)
//          printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
//       break;
//
//      default:
//        printf("\tAddress Family Name: Unknown\n");
//        break;
//    }
//  }
//  printf("\n");
//}
//
//
//
///* From tcptraceroute, convert a numeric IP address to a string */
//#define IPTOSBUFFERS    12
//char *iptos(u_long in)
//{
//    static char output[IPTOSBUFFERS][3*4+3+1];
//    static short which;
//    u_char *p;
//
//    p = (u_char *)&in;
//    which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
//    _snprintf_s(output[which], sizeof(output[which]), sizeof(output[which]),"%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
//    return output[which];
//}
//
//char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
//{
//    socklen_t sockaddrlen;
//
//    #ifdef WIN32
//    sockaddrlen = sizeof(struct sockaddr_in6);
//    #else
//    sockaddrlen = sizeof(struct sockaddr_storage);
//    #endif
//
//
//    if(getnameinfo(sockaddr, 
//        sockaddrlen, 
//        address, 
//        addrlen, 
//        NULL, 
//        0, 
//        NI_NUMERICHOST) != 0) address = NULL;
//
//    return address;
//}

//==========================================================================================================

//#include "pcap.h"
//
//int main()
//{
//    pcap_if_t *alldevs;
//    pcap_if_t *d;
//    int i=0;
//    char errbuf[PCAP_ERRBUF_SIZE];
//    
//    /* Retrieve the device list from the local machine */
//	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
//    {
//        fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
//        exit(1);
//    }
//    
//    /* Print the list */
//    for(d= alldevs; d != NULL; d= d->next)
//    {
//        printf("%d. %s", ++i, d->name);
//        if (d->description)
//            printf(" (%s)\n", d->description);
//        else
//            printf(" (No description available)\n");
//    }
//    
//    if (i == 0)
//    {
//        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
//        return 0;
//    }
//
//    /* We don't need any more the device list. Free it */
//    pcap_freealldevs(alldevs);
//}
